package com.jmyd.coupon.server.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.page.PageMethod;
import com.jmyd.commons.base.service.impl.BaseServiceImpl;
import com.jmyd.commons.base.support.SystemUserSupport;
import com.jmyd.commons.base.vo.PageBean;
import com.jmyd.commons.domain.po.SysUser;
import com.jmyd.commons.exception.CustomException;
import com.jmyd.coupon.server.domain.dto.*;
import com.jmyd.coupon.server.domain.po.SceneCoupon;
import com.jmyd.coupon.server.domain.po.SceneCouponDrawRecord;
import com.jmyd.coupon.server.domain.vo.SceneCouponDrawRecordVo;
import com.jmyd.coupon.server.domain.vo.SceneCouponUseRecordVo;
import com.jmyd.coupon.server.domain.vo.SceneCouponVo;
import com.jmyd.coupon.server.enums.SceneCouponUseStatusEnum;
import com.jmyd.coupon.server.manager.SceneCouponManager;
import com.jmyd.coupon.server.mapper.SceneCouponDrawRecordMapper;
import com.jmyd.coupon.server.mapper.SceneCouponMapper;
import com.jmyd.coupon.server.mapper.SceneCouponUseRecordMapper;
import com.jmyd.coupon.server.service.ISceneCouponService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;

@Service
public class SceneCouponServiceImpl extends BaseServiceImpl<Long, SceneCouponDto, SceneCouponVo> implements ISceneCouponService {

    @Resource
    private SceneCouponMapper sceneCouponMapper;
    @Resource
    private SceneCouponUseRecordMapper sceneCouponUseRecordMapper;
    @Resource
    private SceneCouponDrawRecordMapper sceneCouponDrawRecordMapper;
    @Resource
    private SceneCouponManager sceneCouponManager;
    @Resource
    private SystemUserSupport systemUserSupport;

    @Override
    public PageBean<SceneCouponVo> queryPageList(SceneCouponQueryDto queryDto, HttpServletRequest request) {
        SceneCoupon po = new SceneCoupon().build(queryDto);
        po.setCreatedBy(this.systemUserSupport.getUserId(request));
        Page<Object> page = PageMethod.startPage(queryDto.getPageNum(), queryDto.getPageSize());
        List<SceneCoupon> poList = this.sceneCouponMapper.selectList(po);
        List<SceneCouponVo> voList = new SceneCouponVo().buildVoList(poList);
        return new PageBean<>(voList, page);
    }

    @Override
    public SceneCouponVo queryById(Long id) {
        SceneCoupon po = this.sceneCouponMapper.selectByPrimaryKey(id);
        return new SceneCouponVo().buildVo(po);
    }

    /**
     * 保存优惠券模板
     *
     * @param dto
     * @author samphin
     * @since 2021-7-15 09:17:14
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean save(SceneCouponDto dto, HttpServletRequest request) {
        SceneCoupon po = new SceneCoupon().build(dto);
        po.setCreateTs(new Date());
        po.setCreatedBy(this.systemUserSupport.getUserId(request));
        return this.sceneCouponMapper.insertSelective(po) > 0;
    }

    @Override
    public boolean updateById(SceneCouponUpdateDto dto, HttpServletRequest request) {
        SceneCoupon po = new SceneCoupon().build(dto);
        po.setUpdateTs(new Date());
        po.setUpdatedBy(this.systemUserSupport.getUserId(request));
        return this.sceneCouponMapper.updateByPrimaryKeySelective(po) > 0;
    }

    /**
     * 删除模板ID
     *
     * @param id 模板ID
     * @author samphin
     * @since 2021-7-15 09:17:14
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteById(Long id) {
        this.sceneCouponManager.validateIsUsedCoupon(id);
        return this.sceneCouponMapper.deleteByPrimaryKey(id) > 0;
    }

    @Override
    public boolean grantCoupon(SceneGrantCouponDto couponDto) {
        try {
            //通过优惠券模版ID，获取优惠券信息
            List<SceneCouponDrawRecord> poList = new SceneCouponDrawRecord().build(couponDto, 2);
            return sceneCouponDrawRecordMapper.batchInsert(poList) > 0;
        } catch (Exception e) {
            throw new CustomException("领取优惠券失败");
        }
    }

    /**
     * 领取优惠券
     *
     * @param drawCouponDto
     * @author samphin
     * @since 2021-7-15 09:17:14
     */
    @Override
    public boolean drawCoupon(SceneDrawCouponDto drawCouponDto, HttpServletRequest request) {
        SysUser currentUser = this.systemUserSupport.getUser(request);
        //校验是否重复领取
        this.sceneCouponManager.validateDrawCoupon(currentUser.getId(), drawCouponDto.getCouponId());
        //通过优惠券模版ID，获取优惠券信息
        SceneCouponDrawRecord sceneCouponDrawRecord = new SceneCouponDrawRecord().build(drawCouponDto, currentUser);
        return this.sceneCouponDrawRecordMapper.insertSelective(sceneCouponDrawRecord) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean drawFreeOfChargeCoupon(HttpServletRequest request) {
        try {
            String userId = this.systemUserSupport.getUserId(request);
            //查询免费券
            SceneCoupon sceneCoupon = this.sceneCouponMapper.selectFreeOfChargeCoupon();
            //校验是否重复领取
            this.sceneCouponManager.validateDrawCoupon(userId, sceneCoupon.getId());
            SceneCouponDrawRecord po = new SceneCouponDrawRecord().build(userId, sceneCoupon.getId(), 2);
            return this.sceneCouponDrawRecordMapper.insert(po) > 0;
        } catch (Exception e) {
            throw new CustomException("用户注册领取免单优惠券失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean useCoupon(SceneUseCouponDto sceneUseCouponDto, HttpServletRequest request) {
        try {
            SceneCoupon record = new SceneCoupon();
            record.setId(sceneUseCouponDto.getCouponId());
            record.setUseStatus(SceneCouponUseStatusEnum.USED.getCode());
            boolean bl = this.sceneCouponMapper.updateByPrimaryKeySelective(record) > 0;
            //获取当前用户信息
            SysUser sysUser = this.systemUserSupport.getUser(request);
            //添加一条使用记录
            this.sceneCouponManager.saveUseRecord(sysUser, sceneUseCouponDto);
            return bl;
        } catch (Exception e) {
            throw new CustomException("优惠券使用失败.");
        }
    }

    @Override
    public List<SceneCouponVo> queryNoUseCouponList(String userId) {
        List<SceneCoupon> poList = this.sceneCouponMapper.selectNoUseCoupon(userId);
        return new SceneCouponVo().buildVoList(poList);
    }

    @Override
    public List<SceneCouponVo> queryExpiredCouponList(String userId) {
        List<SceneCoupon> poList = this.sceneCouponMapper.selectExpiredCouponList(userId);
        return new SceneCouponVo().buildVoList(poList);
    }

    /**
     * 查询优惠券使用信息列表
     *
     * @param queryDto
     * @author samphin
     * @date 2019-9-4 15:24:00
     */
    @Override
    public PageBean<SceneCouponUseRecordVo> queryCouponUseRecordList(SceneCouponUsedRecordQueryDto queryDto) {
        Page<Object> page = PageMethod.startPage(queryDto.getPageNum(), queryDto.getPageSize());
        List<SceneCouponUseRecordVo> voList = this.sceneCouponUseRecordMapper.selectList(queryDto);
        voList = new SceneCouponUseRecordVo().build(voList);
        return new PageBean<>(voList, page);
    }

    /**
     * 查询优惠券领取列表
     *
     * @param queryDto 查询对象
     * @author samphin
     * @date 2019-9-4 15:24:00
     */
    @Override
    public PageBean<SceneCouponDrawRecordVo> queryCouponDrawList(SceneCouponDrawQueryDto queryDto) {
        Page<Object> page = PageMethod.startPage(queryDto.getPageNum(), queryDto.getPageSize());
        List<SceneCouponDrawRecordVo> voList = this.sceneCouponDrawRecordMapper.selectList(queryDto.getCouponName(), queryDto.getCouponCode(), null);
        voList = new SceneCouponDrawRecordVo().build(voList);
        return new PageBean<>(voList, page);
    }

    /**
     * 查询优惠券领取列表
     *
     * @param queryDto 查询对象
     * @author samphin
     * @date 2021-7-30 15:55:50
     */
    @Override
    public PageBean<SceneCouponDrawRecordVo> queryMyCouponDrawList(SceneCouponDrawQueryDto queryDto, HttpServletRequest request) {
        String userId = this.systemUserSupport.getUserId(request);
        Page<Object> page = PageMethod.startPage(queryDto.getPageNum(), queryDto.getPageSize());
        List<SceneCouponDrawRecordVo> voList = this.sceneCouponDrawRecordMapper.selectList(queryDto.getCouponName(), queryDto.getCouponCode(), userId);
        voList = new SceneCouponDrawRecordVo().build(voList);
        return new PageBean<>(voList, page);
    }
}
